package com.ihrm.system.controller;

import com.ihrm.common.controller.BaseController;
import com.ihrm.common.entity.PageResult;
import com.ihrm.common.entity.Result;
import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.utils.ExcelUtil;
import com.ihrm.common.utils.JwtUtils;
import com.ihrm.domain.company.Department;
import com.ihrm.domain.system.User;
import com.ihrm.domain.system.response.ProfileResult;
import com.ihrm.domain.system.response.UserResult;
import com.ihrm.domain.system.response.UserSimpleResult;
import com.ihrm.system.feign.DepartmentFeignClient;
import com.ihrm.system.service.PermissionService;
import com.ihrm.system.service.UserService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 小伟
 * @version V1.0
 * @Package com.ihrm.system.controller
 * @date 2020/12/12 18:12
 * @Copyright © 2020-2021 郑州恒星科技有限责任公司
 * 用户操作controller
 */
@RestController
@RequestMapping("/sys")
public class UserController extends BaseController {
    @Autowired
    UserService userService;
    @Autowired
    JwtUtils jwtUtils;
    @Autowired
    PermissionService permissionService;
    @Autowired
    DepartmentFeignClient departmentFeignClient;
    @Autowired
    ExcelUtil excelUtil;
    /**
     * feign微服务调用测试
     */
    @GetMapping("/test/{id}")
    public Result feignTest(@PathVariable String id) throws Exception {
        return departmentFeignClient.findById(id);
    }
    @PostMapping("/test2")
    public Department feignTest2(@RequestParam("code") String code,
                                 @RequestParam("companyId") String companyId) throws Exception {
        return departmentFeignClient.findByCode(code,companyId);
    }
    /**
     * 批量导入用户信息
     */
    @PostMapping("/user/import")
    public Result addAllUsers(MultipartFile file) throws Exception {
        //构建用户信息
        List<User> userList = new ArrayList<>();
        //获取文件流信息
        InputStream inputStream = file.getInputStream();
        //创建工作簿
        Workbook wb = new XSSFWorkbook(inputStream);
        //获取sheet
        Sheet sheet = wb.getSheetAt(0);
        //遍历行 sheet.getLastRowNum()从0开始 到最后一行 值为索引
        for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
            //根据行索引获取行对象
            Row row = sheet.getRow(rowIndex);
            //构建属性对象
            Object[] values = new Object[row.getLastCellNum()];
            for (int colIndex = 1; colIndex < row.getLastCellNum(); colIndex++) {
                //获取单元格对象
                Cell cell = row.getCell(colIndex);
                //获取单元格值并保存到数组中
                values[colIndex]=excelUtil.getCellValue(cell);
            }
            //构建用户信息对象
            User user = new User(values);
            userList.add(user);
        }
        userService.addAll(userList,companyId,companyName);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 新增企业用户
     *
     * @param user 用户信息
     * @return 添加结果
     */
    @PostMapping("/user")
    public Result addUser(@RequestBody User user) {
        user.setCompanyId(companyId);
        user.setCompanyName(companyName);
        userService.saveUser(user);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 修改企业用户信息
     *
     * @param id   用户id
     * @param user 修改信息
     * @return 修改结果
     */
    @RequiresPermissions("api-user-update")
    @PutMapping("/user/{id}")
    public Result updateUser(@PathVariable String id, @RequestBody User user) {
        user.setId(id);
        userService.updateUser(user);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 根据id查询用户信息
     *
     * @param id 用户id
     * @return 查询结果
     */
    @GetMapping("/user/{id}")
    public Result findById(@PathVariable String id) {
        User user = userService.findById(id);
        //构建返回对象，加入用户角色id集合用于数据回显
        UserResult userResult = new UserResult(user);
        return new Result(ResultCode.SUCCESS, userResult);
    }

    /**
     * 根据企业查询员工列表
     * @throws Exception
     */
    @RequestMapping(value = "/user/simple", method = RequestMethod.GET)
    public Result simple() throws Exception {
        List<UserSimpleResult> list = new ArrayList<>();
        List<User> users = userService.findAllSimple(super.companyId);
        for (User user : users) {
            list.add(new UserSimpleResult(user.getId(),user.getUsername()));
        }
        return new Result(ResultCode.SUCCESS,list);
    }
    /**
     * 根据id删除用户信息
     *
     * @param id 用户id
     * @return 删除结果
     */
    @RequiresPermissions("api-user-delete")
    @DeleteMapping(value = "/user/{id}")
    public Result deleteById(@PathVariable String id) {
        userService.deleteById(id);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 根据企业id查询全部用户信息
     *
     * @return 查询结果
     */
    @GetMapping("/user")
    public Result findAll(int page, int size, @RequestParam Map map) {
        map.put("companyId", companyId);
        Page userPage = userService.findAll(page, size, map);
        PageResult<User> pageResult = new PageResult<User>(userPage.getTotalElements(), userPage.getContent());
        return new Result(ResultCode.SUCCESS, pageResult);
    }

    /**
     * 为用户分配权限
     *
     * @param map 参数列表
     *            id:用户id
     *            roleIds:用户分配的角色id集合
     * @return
     */
    @PutMapping("/user/assignRoles")
    public Result assignRoles(@RequestBody Map<String, Object> map) {
        String userId = (String) map.get("id");
        List<String> roleIds = (List<String>) map.get("roleIds");
        userService.assignRoles(userId, roleIds);
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * 用户登录
     *
     * @param loginMap 登录参数
     *                 mobile：用户手机号
     *                 password: 用户密码
     * @return 登录结果
     */
    @PostMapping(value = "/login")
    public Result doLogin(@RequestBody Map<String, String> loginMap) {
        String mobile = loginMap.get("mobile");
        String password = loginMap.get("password");
        //密码使用MD5加盐加密
        password = new Md5Hash(password, mobile, 3).toString();
        UsernamePasswordToken upToken = new UsernamePasswordToken(mobile, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            //验证登录
            subject.login(upToken);
            String sessionId = (String) subject.getSession().getId();
            return new Result(ResultCode.SUCCESS, sessionId);
        } catch (UnknownAccountException | IncorrectCredentialsException exception) {
            return new Result(ResultCode.MOBILEORPASSOWRD_ERROR);
        }
    }

    /**
     * 用户授权
     *
     * @return 个人授权信息
     * @throws Exception token验证失败
     */
    @PostMapping(value = "/profile")
    public Result getProfile() {
        //获取session中的安全数据
        Subject subject = SecurityUtils.getSubject();
        //1.subject获取所有的安全数据集合
        PrincipalCollection principals = subject.getPrincipals();
        //2.获取安全数据
        ProfileResult result = (ProfileResult)principals.getPrimaryPrincipal();
        System.out.println(subject.getSession().getId());
        return new Result(ResultCode.SUCCESS, result);
    }

    /**
     * 上传用户头像到七牛云存储
     * @param id 用户id
     * @param file 头像文件
     * @return 头像访问URL
     */
    @PostMapping("/user/upload/{id}")
    public Result uploadStaffPhoto(@PathVariable String id,@RequestParam("file") MultipartFile file) throws IOException {
      String imgUrl =  userService.uploadStaffPhoto(id, file);
        return new Result(ResultCode.SUCCESS,imgUrl);
    }
}
